
package com.csscis.ssm.core.util;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import org.codehaus.jackson.JsonGenerationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.AnnotatedElement;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * json 数据处理
 * 以及json时间转换
 *
 * @author de
 *
 */
@SuppressWarnings("serial")
@Component
public class JsonUtils {

    private static Logger logger = LoggerFactory.getLogger(JsonUtils.class);
    private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static final ObjectMapper mapper;

    public ObjectMapper getMapper() {

        return mapper;
    }

    static {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT);

        mapper = new ObjectMapper();
        mapper.setDateFormat(dateFormat);
        mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {

            @Override
            public Object findSerializer(Annotated a) {

                if (a instanceof AnnotatedMethod) {
                    AnnotatedElement m = a.getAnnotated();
                    DateTimeFormat an = m.getAnnotation(DateTimeFormat.class);
                    if (an != null) {
                        if (!DEFAULT_DATE_FORMAT.equals(an.pattern())) {
                            return new JsonDateSerializer(an.pattern());
                        }
                    }
                }
                return super.findSerializer(a);
            }
        });
    }

    /**
     * @param obj
     * @return
     */
    public static String toJson(Object obj) {

        try {
            return mapper.writeValueAsString(obj);
        } catch (Exception e) {
            throw new RuntimeException("转换json字符失败!");
        }
    }

    /**
     * @param json
     * @param clazz
     * @return
     */
    public <T> T toObject(String json, Class<T> clazz) {

        try {
            return mapper.readValue(json, clazz);
        } catch (IOException e) {
            throw new RuntimeException("将json字符转换为对象时失败!");
        }
    }

    public static class JsonDateSerializer extends JsonSerializer<Date> {

        private SimpleDateFormat dateFormat;

        public JsonDateSerializer(String format) {
            dateFormat = new SimpleDateFormat(format);
        }

        @Override
        public void serialize(
                Date date,
                JsonGenerator gen,
                SerializerProvider provider) throws IOException,
                JsonProcessingException {

            String value = dateFormat.format(date);
            gen.writeString(value);
        }
    }

    //上面的是对返回结果json时间格式处理

    /**
     * 处理结果
     * @param obj
     * @return
     */
    private static String getDataJson(Object obj) {

        try {
            ObjectMapper objMapper = new ObjectMapper();
            String tree = objMapper.writeValueAsString(obj);
            byte[] byteUTF8 = tree.getBytes(Charset.forName("utf-8"));
            return new String(byteUTF8, "utf-8");
        } catch (JsonProcessingException e) {
            logger.error("json 格式转换出错", e);
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            logger.error(e.getMessage(), e);
            e.printStackTrace();
            return "";
        }
        return null;
    }

    //上面的是对返回结果json时间格式处理

    /**
     * 返回json字符串
     *
     * @param map
     * @return
     * @throws JsonGenerationException
     * @throws JsonMappingException
     * @throws IOException
     */
    @SuppressWarnings("rawtypes")
    public static String jsonResult(Map map) {

        return getDataJson(map);
    }

    /**
     * 返回json字符串
     *
     * @param map
     * @return
     * @throws JsonGenerationException
     * @throws JsonMappingException
     * @throws IOException
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static String jsonResult(List list) {

        Map map = new HashMap();
        map.put("Rows", list);
        if (list != null) {
            map.put("Total", list.size());
        } else {
            map.put("Total", 0);
        }
        return jsonResult(map);
    }

    /**
     * 返回json字符串
     *
     * @param map
     * @return
     * @throws JsonGenerationException
     * @throws JsonMappingException
     * @throws IOException
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static String jsonResult(List list, Integer total)
            throws IOException {

        Map map = new HashMap();
        map.put("Rows", list);
        map.put("Total", total);
        return jsonResult(map);
    }

    /**
     * 输出json字符串
     * @param object
     * @param response
     */
    public static void jsonResult(String str, HttpServletResponse response) {

        response.setCharacterEncoding("UTF-8");
        try {
            response.getWriter().write(str.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 输出验证结果，返回true 表示不存在，返回false表示已经存在
     * @param list
     * @param response
     */
    @SuppressWarnings("rawtypes")
    public static void checkResult(List list, HttpServletResponse response) {

        if (list != null && list.size() > 0) {
            JsonUtils.jsonResult("false", response);
        } else {
            JsonUtils.jsonResult("true", response);
        }
    }

}
